/**********************************************************************************************************
** 驱动文件：	jmkt-STXXX.c
** 驱动类型：	jmkt
** 设备名称：	精密空调
** 设备型号：	STXXX
** 设备品牌：	科士达
** 设备协议：	Modbus-RTU
** 驱动描述：	适用于科士达StationAir系列精密空调机组,如：ST005、ST007、ST012、ST017、ST020
** 生成日期：	2019-07-18 16:46:34
**********************************************************************************************************/
#include "Includes.h"


/**********************************************************************************************************
* 定义设备数据点变量结构
**********************************************************************************************************/
typedef struct{
	Var IndoorTemperature;						//室内温度
	Var IndoorHumidity;							//室内湿度
	Var TemperatureSetting;						//温度设定
	Var HumiditySetting;						//湿度设定
	Var OnOff;									//开关机状态
	Var FanStatus;								//风机状态
	Var HeaterStatus;							//电加热状态
	Var CompressorStatus;						//压缩机状态
	Var HumidifierStatus;						//加湿器状态
	Var Fault;									//故障
	Var ExhaustSensor;							//排气探头
	Var HumiditySensor;							//湿度探头
	Var TemperatureSensor;						//室内温度探头
	Var CompressorPressure;						//压缩机高/低压报警
	Var HeaterOverload;							//电加热过载
	Var TemperatureAlarm;						//温度报警
	Var FanOverloadOrPowerFailure;				//风机过载或电源故障
	Var FanFailure;								//外风机失效
}Data_Struct;									//定义变量结构


/**********************************************************************************************************
* 设备数据点变量属性声明
**********************************************************************************************************/
const static Var_Property_Def var_attr[] = {
	{
		FLOAT,
		0,
		READONLY,
		"IndoorTemperature",
		"室内温度",
		"℃",
		"室内温度",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		FLOAT,
		0,
		READONLY,
		"IndoorHumidity",
		"室内湿度",
		"%",
		"室内湿度",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		FLOAT,
		0,
		READONLY,
		"TemperatureSetting",
		"温度设定",
		"℃",
		"温度设定",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		FLOAT,
		0,
		READONLY,
		"HumiditySetting",
		"湿度设定",
		"%",
		"湿度设定",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"OnOff",
		"开关机状态",
		"",
		"开关机状态：0-关机；1-开机",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"FanStatus",
		"风机状态",
		"",
		"风机运行状态：0-停止；1-运行",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"HeaterStatus",
		"电加热状态",
		"",
		"电加热运行状态：0-停止；1-运行",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"CompressorStatus",
		"压缩机状态",
		"",
		"压缩机运行状态：0-停止；1-运行",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"HumidifierStatus",
		"加湿器状态",
		"",
		"加湿器运行状态：0-停止；1-运行",
		0,
		0,
		"",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"Fault",
		"故障",
		"",
		"故障：0-无故障；1-故障",
		0,
		0,
		"故障",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"ExhaustSensor",
		"排气探头",
		"",
		"排气探头：0-正常；1-故障",
		0,
		0,
		"故障",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"HumiditySensor",
		"湿度探头",
		"",
		"湿度探头：0-正常；1-故障",
		0,
		0,
		"故障",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"TemperatureSensor",
		"室内温度探头",
		"",
		"室内温度探头：0-正常；1-故障",
		0,
		0,
		"故障",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"CompressorPressure",
		"压缩机高/低压报警",
		"",
		"压缩机高低压报警：0-无报警；1-高压报警；2-低压报警",
		0,
		0,
		"报警",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"HeaterOverload",
		"电加热过载",
		"",
		"电加热过载：0-无过载；1-过载报警",
		0,
		0,
		"报警",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"TemperatureAlarm",
		"温度报警",
		"",
		"温度报警：0-正常；1-高温报警；2-低温报警",
		0,
		0,
		"报警",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"FanOverloadOrPowerFailure",
		"风机过载或电源故障",
		"",
		"风机过载或电源故障：0-无报警；1-报警",
		0,
		0,
		"报警",
		"",
		0.000,
		0.000
	},
	{
		OCTSTR,
		0,
		READONLY,
		"FanFailure",
		"外风机失效",
		"",
		"外风机失效：0-正常；1-失效",
		0,
		0,
		"故障",
		"",
		0.000,
		0.000
	}
};


/**********************************************************************************************************
* 函数名称： static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
* 函数说明： 生成获取传感器数据指令
* 输入参数： 指令索引，传感器地址，变量结构体指针,以及指令缓存区指针,指令长度
* 返回参数： 无
**********************************************************************************************************/
static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
{
	switch(index)
	{
		case 0:
			cmd[0] = addr;
			cmd[1] = 0x01;
			cmd[2] = 0x00;								
			cmd[3] = 0x80;
			cmd[4] = 0x00;
			cmd[5] = 0x05;
			*len = CRC16_Padding(cmd, 6);
			break;
		case 1:
			cmd[0] = addr;
			cmd[1] = 0x01;
			cmd[2] = 0x00;								
			cmd[3] = 0x00;
			cmd[4] = 0x00;
			cmd[5] = 0x10;
			*len = CRC16_Padding(cmd, 6);			
			break;		
		case 2:
			cmd[0] = addr;
			cmd[1] = 0x03;
			cmd[2] = 0x00;								
			cmd[3] = 0x02;
			cmd[4] = 0x00;
			cmd[5] = 0x02;
			*len = CRC16_Padding(cmd, 6);			
			break;	
		case 3:
			cmd[0] = addr;
			cmd[1] = 0x03;
			cmd[2] = 0x02;								
			cmd[3] = 0xBF;
			cmd[4] = 0x00;
			cmd[5] = 0x02;
			*len = CRC16_Padding(cmd, 6);			
			break;			
		case 4:
			cmd[0] = addr;
			cmd[1] = 0x01;
			cmd[2] = 0x00;								
			cmd[3] = 0xB0;
			cmd[4] = 0x00;
			cmd[5] = 0x01;
			*len = CRC16_Padding(cmd, 6);			
			break;
		default:
			break;
	}
}


/**********************************************************************************************************
* 函数名称： static int parse_fun(short index, int addr, void *data, char *buf, short len)
* 函数说明： 解析传感器响应的数据，并写入数据库
* 输入参数： 解析索引,传感器地址，变量结构体指针，以及响应数据缓存取指针，响应数据长度
* 返回参数： 返回解析结果，返回0成功，返回1失败
**********************************************************************************************************/
static int parse_fun(short index, int addr, void *data, char *buf, short len)
{
	union{
		short 			dat16;
      	unsigned char  	dat8[2];
    }DAT16_8;						   //数据类型转换	
	Data_Struct	*d = (Data_Struct*)data;

	if(buf!=NULL && len>0 )
	{
		switch(index)
		{
			case 0:
				d->FanStatus.value.str					= buf[3]&0x01?"运行":"停止";
				Set_Var_Status(&d->FanStatus,			  buf[3]&0x01?ON:OFF, NULL);	
				d->HeaterStatus.value.str				= buf[3]&0x02?"运行":"停止";
				Set_Var_Status(&d->HeaterStatus,		  buf[3]&0x02?ON:OFF, NULL);					
				d->CompressorStatus.value.str			= buf[3]&0x04?"运行":"停止";
				Set_Var_Status(&d->CompressorStatus,	  buf[3]&0x04?ON:OFF, NULL);					
				d->HumidifierStatus.value.str			= buf[3]&0x08?"运行":"停止";
				Set_Var_Status(&d->HumidifierStatus,	  buf[3]&0x08?ON:OFF, NULL);					
				d->Fault.value.str						= "预留";
				Set_Var_Status(&d->Fault,				  Normal, NULL);
				break;
			case 1:
				d->ExhaustSensor.value.str				= buf[3]&0x01?"报警":"正常";
				Set_Var_Status(&d->ExhaustSensor,		  buf[3]&0x01?Alarm:Normal, NULL);
				d->HumiditySensor.value.str				= buf[3]&0x08?"故障":"正常";
				Set_Var_Status(&d->HumiditySensor,		  buf[3]&0x08?Alarm:Normal, NULL);
				d->TemperatureSensor.value.str			= buf[3]&0x10?"故障":"正常";
				Set_Var_Status(&d->TemperatureSensor,	  buf[3]&0x10?Alarm:Normal, NULL);
				if(buf[3]&0x20){
					d->CompressorPressure.value.str		= "高压报警";
					Set_Var_Status(&d->CompressorPressure, Alarm, NULL);
				}
				else if(buf[3]&0x40){
					d->CompressorPressure.value.str		= "低压报警";
					Set_Var_Status(&d->CompressorPressure, Alarm, NULL);
				}
				else{
					d->CompressorPressure.value.str		= "正常";
					Set_Var_Status(&d->CompressorPressure, Normal, NULL);					
				}				
				d->HeaterOverload.value.str				= buf[4]&0x02?"报警":"正常";
				Set_Var_Status(&d->HeaterOverload,		  buf[4]&0x02?Alarm:Normal, NULL);
				if(buf[4]&0x08){
					d->TemperatureAlarm.value.str		= "低温报警";
					Set_Var_Status(&d->TemperatureAlarm, Alarm, NULL);
				}
				else if(buf[4]&0x10){
					d->TemperatureAlarm.value.str		= "高温报警";
					Set_Var_Status(&d->TemperatureAlarm, Alarm, NULL);
				}
				else{
					d->TemperatureAlarm.value.str		= "正常";
					Set_Var_Status(&d->TemperatureAlarm, Normal, NULL);				
				}
				d->FanOverloadOrPowerFailure.value.str	= buf[4]&0x20?"报警":"正常";
				Set_Var_Status(&d->FanOverloadOrPowerFailure, buf[4]&0x20?Alarm:Normal, NULL);
				d->FanFailure.value.str					= buf[4]&0x80?"报警":"正常";
				Set_Var_Status(&d->FanFailure,			  buf[4]&0x80?Alarm:Normal, NULL);
				break;
			case 2:
				DAT16_8.dat8[1] = buf[3];
				DAT16_8.dat8[0] = buf[4];
				d->TemperatureSetting.value.fnum = DAT16_8.dat16*0.1;
				DAT16_8.dat8[1] = buf[5];
				DAT16_8.dat8[0] = buf[6];
				d->HumiditySetting.value.fnum = DAT16_8.dat16*0.1;				
				break;
			case 3:
				DAT16_8.dat8[1] = buf[3];
				DAT16_8.dat8[0] = buf[4];
				d->IndoorHumidity.value.fnum = DAT16_8.dat16*0.1;
				DAT16_8.dat8[1] = buf[5];
				DAT16_8.dat8[0] = buf[6];
				d->IndoorTemperature.value.fnum = DAT16_8.dat16*0.1;					
				break;				
			case 4:
				d->OnOff.value.str		= buf[3]&0x01?"开机":"关机";
				Set_Var_Status(&d->OnOff, buf[3]&0x01?ON:OFF, NULL);
				break;
			default:
				break;
		}
		return 0;
	}
	return 1;
}


/**********************************************************************************************************
* 函数名称： void jmkt_STXXX_Registration(void)
* 函数说明： 精密空调驱动注册
* 输入参数： 无
* 返回参数： 无
**********************************************************************************************************/
void jmkt_STXXX_Registration(void)
{
	DeviceRegWithResTimeout(
		"jmkt",													//设备类型
		"精密空调",												//设备名称（导航栏默认显示名称）
		"STXXX",												//设备型号
		"适用于科士达StationAir系列精密空调机组,如：ST005、ST007、ST012、ST017、ST020",//驱动描述
		var_attr,												//变量属性声明
		sizeof(Data_Struct),									//变量结构体空间大小
		cmd_fun,												//发送指令生成函数
		parse_fun,												//数据解析函数
		250														//设备响应超时时间
	);
}

